(function(f){
	var a={
			errorRequired:"此项为必填项",
			errorTempl:'<span class="validate-error">{msg}</span>',
			optionTempl:'<span class="validate-option">{msg}</span>',
			callback:null},
			c=".item",
			b=".validate-error",
			e=".validate-option",
			d=function(i,h,k,g,j){
				if(!h||!i){return}
				this.asyncList=[];
				this.asyncEndHandle=null;
				this._init(i,h,k,g,j)};
			d.prototype={
				_init:function(i,h,l,g,k){
					var j;j=this.node=f(i);
					this.form=(j[0].tagName.toLowerCase()==="form")?j:j.find("form");
					this.config=f.extend(a,k);
					this.rules=h;
					this.errorMsg=l||{};
					this.optionMsg=g||{};
					j.data("validateForm",this);
					this._bindEvent()},
				_bindEvent:function(){
					if(this.node.data("hasBindValidateEvent")){return}
					this.node.data("hasBindValidateEvent",true);
					this.form.submit(f.proxy(function(g){g.preventDefault();
					this.validate();
					this._handleFormSubmit()},
					this)).find("input, select, textarea").bind({
						blur:f.proxy(function(g){this._handleBlur(g)},this),
						focus:f.proxy(function(g){this._handleFocus(g)},this)});
					this._bindRules()},
				_bindRules:function(){var h=this.rules,g;for(g in h){
					if(h.hasOwnProperty(g)){f(h[g].elems,this.form).each(function(k,m){var j=f(m),
						l=j.data("validate-rules")||"";
					j.data("validate-rules",l+","+g)})}}},
				_handleBlur:function(n){
					var h=f(n.target),o=h.parents(c).eq(0),l,g,m,j,p=false,q=h.data("validate-rules");
					o.find(e).hide();if(!q){return}
					q=q.split(",").slice(1);for(l=0,m=q.length;l<m;l++){g=this.rules[q[l]];
					this.validate(g,this.errorMsg[q[l]],h)}},
				_handleFocus:function(h){var g=h.target.getAttribute("name"),
				i;if(!g){return}if(i=this.optionMsg[g.toLowerCase()]){this.displayOptionMsg(f(h.target),i)}},
				_handleFormSubmit:function(){
					var h,g,i=this;h=this.form.find(".has-error");
					if(h.length>0){f(i.form).trigger("hasError");return}g=this.form.find(".has-process");
					if(g.length>0){this.asyncEndHandle=function(){i.asyncEndHandle=null;
					i._handleFormSubmit()};
					return}if(i.config.callback){i.config.callback(i.form)}else{i.form[0].submit()}},
					clearErrorMsg:function(g){var h=g.parents(c).eq(0);h.find(b).hide()},
					displayError:function(i,k){var j=i.parents(c).eq(0),h=j.find(e),g=j.find(b);h.hide();
					if(g.length===0){f(this.config.errorTempl.replace("{msg}",k)).appendTo(j).show();
					return}g.show().html(k);return},displayOptionMsg:function(i,k){if(!k){return}
					var j=i.parents(c).eq(0),h=j.find(e),g=j.hasClass("has-error");
					if(g){return}if(h.length===0){f(this.config.optionTempl.replace("{msg}",k)).appendTo(j).show();
					return}h.show().html(k);return},
					asyncValidate:function(i,h,g){if(!i||!h){return}var j=i.parent();
					if(j.hasClass("has-process")){return}j.addClass("has-process");
					this.asyncList.push(f.getJSON(h,f.proxy(function(k){var l=this.asyncList;g&&g(k);j.removeClass("has-process");
					this.asyncList.pop();if(l.length===0){this.asyncEndHandle&&this.asyncEndHandle()}},this)));
					f("body").ajaxError(function(){alert("远程验证失败！\n请稍候重试或将此问题反馈给我们(help@Share.com)")})},
					validate:function(m,l,h){var i=this.errorMsg.errorRequired,
						n=function(v,x,t,w){var u=t.parents(c).eq(0),q=false,s;if(v.isRequired&&f.trim(t.val())===""){
							w.displayError(t,i||a.errorRequired);q=true;u.addClass("has-error")
							}else{for(s in v){if(v.hasOwnProperty(s)&&typeof v[s]==="function"){if(v[s](t,w)){
								w.displayError(t,x[s]);u.addClass("has-error");q=true;break}}}if(!q){
									w.clearErrorMsg(t);u.removeClass("has-error")}}},g,p,o,j;if(!m){
										p=this.rules;o=this.errorMsg;for(j in p){if(p.hasOwnProperty(j)){g=p[j];f(g.elems,this.form).each(f.proxy(function(k,q){n(g,o[j],f(q),this)},this))}}}else{n(m,l,h,this)}}};f.extend({validate:{isEmail:function(g){return/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(g)}}});f.fn.validateForm=function(j,l,i,k){var h=i,g=k;if(arguments.length===3){h=null;g=i}this.each(function(){new d(this,j,l,h,g)});return this}})(jQuery);
